package org.dllwh.utils.apache.poi.word;


import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.util.Units;
import org.apache.poi.xddf.usermodel.chart.*;
import org.apache.poi.xwpf.usermodel.XWPFChart;
import org.apache.poi.xwpf.usermodel.XWPFDocument;
import org.dllwh.utils.apache.poi.word.model.BarChartForm;
import org.dllwh.utils.apache.poi.word.model.LineChartForm;
import org.dllwh.utils.apache.poi.word.model.PieChartForm;

import java.io.IOException;

/**
 * 把今天最好的表现当作明天最新的起点．．～
 * <p>
 * Today the best performance as tomorrow the newest starter!
 *
 * @ClassName WordChart
 * @Description Word 图表操作工具类
 * @Date 2025-10-31 18:09
 * @版本 V 1.0.1
 * @since JDK 17
 */
public class WordChart {
    /**
     * 生成折线图
     */
    public static void createLineChart(XWPFDocument document, LineChartForm chartForm) throws IOException, InvalidFormatException {
        if (chartForm == null) {
            throw new IllegalArgumentException("绘制图表的数据为空！");
        }
        if (chartForm.getXData() == null) {
            throw new IllegalArgumentException("X轴数据为空！");
        }
        if (chartForm.getYData() == null) {
            throw new IllegalArgumentException("Y轴数据为空！");
        }


        /*
         * 1、创建chart图表对象,抛出异常
         */
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

        /*
         * 2、图表相关设置
         */
        // 图表标题
        chart.setTitleText(chartForm.getChartTitle());
        // 图例是否覆盖标题
        chart.setTitleOverlay(chartForm.isOverlay());

        /*
         * 3、图例设置
         */
        XDDFChartLegend legend = chart.getOrAddLegend();
        // 图例位置:上下左右
        legend.setPosition(LegendPosition.TOP);

        /*
         * 4、X轴(分类轴)相关设置
         */
        // 创建X轴，并且指定位置
        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        // x轴标题
        xAxis.setTitle(chartForm.getXAxisTitle());
        // 设置X轴数据
        XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(chartForm.getXData());

        /*
         * 5、Y轴(值轴)相关设置
         */
        // 创建Y轴，并且指定位置
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);
        // Y轴标题
        yAxis.setTitle(chartForm.getYAxisTitle());
        // 设置Y轴数据
        XDDFNumericalDataSource<Number> yAxisSource = XDDFDataSourcesFactory.fromArray(chartForm.getYData());

        /*
         * 6、创建折线图对象
         */
        XDDFLineChartData lineChart = (XDDFLineChartData) chart.createData(ChartTypes.LINE, xAxis, yAxis);

        /*
         * 7、加载折线图数据集
         */
        XDDFLineChartData.Series lineSeries = (XDDFLineChartData.Series) lineChart.addSeries(xAxisSource, yAxisSource);
        // 图例标题
        lineSeries.setTitle(chartForm.getLegendTitle(), null);
        // 线条样式:true平滑曲线,false折线
        lineSeries.setSmooth(true);
        // 标记点样式
        lineSeries.setMarkerStyle(MarkerStyle.CIRCLE);

        /*
         * 8、绘制折线图
         */
        chart.plot(lineChart);
    }

    /**
     * 创建柱状图
     */
    public static void createBarChart(XWPFDocument document, BarChartForm chartForm) throws IOException, InvalidFormatException {
        /*
         * 1、创建chart图表对象,抛出异常
         */
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

        /*
         * 2、图表相关设置
         */
        // 图表标题
        chart.setTitleText(chartForm.getChartTitle());
        // 标题是否覆盖图表
        chart.setTitleOverlay(chartForm.isOverlay());

        /*
         * 3、图例设置
         */
        XDDFChartLegend legend = chart.getOrAddLegend();
        // 图例位置:上下左右
        legend.setPosition(LegendPosition.TOP);

        /*
         * 4、X轴(分类轴)相关设置
         */
        // 创建X轴,并且指定位置
        XDDFCategoryAxis xAxis = chart.createCategoryAxis(AxisPosition.BOTTOM);
        // x轴标题
        xAxis.setTitle(chartForm.getXAxisTitle());
        // 设置X轴数据
        XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(chartForm.getXData());

        /*
         * 5、Y轴(值轴)相关设置
         */
        // 创建Y轴,指定位置
        XDDFValueAxis yAxis = chart.createValueAxis(AxisPosition.LEFT);
        // Y轴标题
        yAxis.setTitle(chartForm.getYAxisTitle());
        // 设置图柱的位置:BETWEEN居中
        yAxis.setCrossBetween(AxisCrossBetween.BETWEEN);
        // 设置Y轴数据
        XDDFNumericalDataSource<Number> yAxisSource = XDDFDataSourcesFactory.fromArray(chartForm.getYData());

        /*
         * 6、创建柱状图对象
         */
        XDDFBarChartData barChart = (XDDFBarChartData) chart.createData(ChartTypes.BAR, xAxis, yAxis);
        // 设置为可变颜色
        barChart.setVaryColors(true);
        // 设置柱状图的方向:BAR横向,COL竖向,默认是BAR
        barChart.setBarDirection(BarDirection.COL);

        /*
         * 7、加载柱状图数据集
         */
        XDDFBarChartData.Series barSeries = (XDDFBarChartData.Series) barChart.addSeries(xAxisSource, yAxisSource);
        // 图例标题
        barSeries.setTitle(chartForm.getLegendTitle(), null);

        /*
         * 8、绘制柱状图
         */
        chart.plot(barChart);
    }

    /**
     * 创建饼状图
     */
    public static void createPieChart(XWPFDocument document, PieChartForm chartForm) throws IOException, InvalidFormatException {
        /*
         * 1、创建chart图表对象,抛出异常
         */
        XWPFChart chart = document.createChart(15 * Units.EMU_PER_CENTIMETER, 10 * Units.EMU_PER_CENTIMETER);

        /*
         * 2、图表相关设置
         */
        // 图表标题
        chart.setTitleText(chartForm.getChartTitle());
        // 图例是否覆盖标题
        chart.setTitleOverlay(chartForm.isOverlay());

        /*
         * 3、图例设置
         */
        XDDFChartLegend legend = chart.getOrAddLegend();
        // 图例位置:上下左右
        legend.setPosition(LegendPosition.TOP);

        /*
         * 4、X轴(分类轴)相关设置:饼图中的图例显示
         */
        // 设置分类数据
        XDDFCategoryDataSource xAxisSource = XDDFDataSourcesFactory.fromArray(chartForm.getXData());

        /*
         * 5、Y轴(值轴)相关设置:饼图中的圆形显示
         */
        // 设置值数据
        XDDFNumericalDataSource<Number> yAxisSource = XDDFDataSourcesFactory.fromArray(chartForm.getYData());

        /*
         * 6、创建饼图对象,饼状图不需要X,Y轴,只需要数据集即可
         */
        XDDFPieChartData pieChart = (XDDFPieChartData) chart.createData(ChartTypes.PIE, null, null);

        /*
         * 7、加载饼图数据集
         */
        XDDFPieChartData.Series pieSeries = (XDDFPieChartData.Series) pieChart.addSeries(xAxisSource, yAxisSource);
        // 系列提示标题
        pieSeries.setTitle(chartForm.getLegendTitle(), null);

        /*
         * 8、绘制饼图
         */
        chart.plot(pieChart);
    }
}
